// 寒冰箭分裂
// 打中单位后可以分裂
library SimulateAttac6Boom requires SimulateAttack


    // 判断单位是否被指定弹道攻击过，攻击过返回true，否则返回false
    private function isAttack takes unit u, integer id returns boolean
        local integer total = LoadInteger(skht, id, StringHash("穿透个数"))
        local integer i = 1
        loop
            exitwhen i > total
            if LoadInteger(skht, id, i) == GetHandleId(u) then
                return true
            endif
            set i = i + 1
        endloop

        set u = null
        return false
    endfunction

    // 弹道伤害  id为弹道id
    function hbj_boom_damage takes integer uid, integer tid, integer tidi, integer id, real x, real y, real radius, real damage, unit bu returns nothing

        local group g = CreateGroup()
        local boolexpr filter
        local unit ydl_unit
        local unit u = udg_player_select_hero[uid]
        local integer total = LoadInteger(skht, id, StringHash("穿透个数"))
        local integer count = LoadInteger(skht, id, StringHash("当前穿透个数"))
        
        local integer r

        set filter = Condition(function heroSkillConditions)
        call GroupEnumUnitsInRange(g, x, y, radius, filter)

        loop
            set ydl_unit = FirstOfGroup(g)
            exitwhen (ydl_unit == null)
            // 判断该单位是否已经被该弹道攻击过
            call GroupRemoveUnit(g, ydl_unit)
            if not isAttack(ydl_unit, id) and count <= total and ydl_unit != bu then
                // 伤害
                set count = count + 1
                call SaveInteger(skht, id, StringHash("当前穿透个数"), count)
                call SaveInteger(skht, id, count, GetHandleId(ydl_unit))

                call UnitDamageTarget( u, ydl_unit, damage, true, true, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_COLD, WEAPON_TYPE_WHOKNOWS )

                // 是否冻伤
                if ct_hbjBoomIsDS[uid] and FF_GetHp(ydl_unit) >= 1 then
                    call GroupAddUnit(LoadGroupHandle(hbjHash, uid, 1), ydl_unit)
                endif

                // 是否冻结
                if ct_hbjBoomDJ[uid] and FF_GetHp(ydl_unit) >= 1 then

                    call SetUnitAbilityLevel(majiaDJ[uid], 'A008', ct_hbjBoomDJLevel[uid])
                    call SetUnitPosition(majiaDJ[uid], GetUnitX(ydl_unit), GetUnitY(ydl_unit))
                    call IssueTargetOrder(majiaDJ[uid], "thunderbolt", ydl_unit)
                endif
                
                // 是否减速
                if ct_hbjBoomJS[uid] and FF_GetHp(ydl_unit) >= 1 then
                    call SetUnitAbilityLevel(majiaJS[uid], 'A009', ct_hbjBoomJSLevel[uid])
                    call SetUnitPosition(majiaJS[uid], GetUnitX(ydl_unit), GetUnitY(ydl_unit))
                    call IssueTargetOrder(majiaJS[uid], "slow", ydl_unit)
                endif
                
                // 如果穿透数量达到了，销毁弹道
                if count > total then
                    call DestroyEffect(LoadEffectHandle(skht, tid, tidi))
                    call RemoveSavedHandle(skht, tid, tidi)
                endif
            endif
        endloop

        call DestroyBoolExpr(filter)
        call DestroyGroup(g)

        set u = null
        set g = null
        set filter = null
        set ydl_unit = null
    endfunction

    function timer_hbj_boom takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local integer tid = GetHandleId(t)
        local integer uid = LoadInteger(skht, tid, 1)
        local integer num = LoadInteger(skht, tid, 2)
        local real firstLineAngle = LoadReal(skht, tid, 3)
        local real inAngle = LoadReal(skht, tid, 5)
        local integer loopi
        local integer ecthid
        local integer count
        local integer total

        // 每次要移动的距离
        local real jl = LoadReal(skht, tid, 4) + 35
    
        // 计算出马特效的位置
        local real x
        local real y
        // 总距离
        local real totalJl = LoadReal(skht, tid, 12)

        set loopi = 0
        loop
            exitwhen loopi >= num
            
            if LoadEffectHandle(skht, tid, 20 + loopi) != null then
                set x = CosBJ(firstLineAngle) * (jl) + LoadReal(skht, tid, 6)
                set y = SinBJ(firstLineAngle) * (jl) + LoadReal(skht, tid, 7)
                // 设置弹道位置
                call EXSetEffectXY( LoadEffectHandle(skht, tid, 20 + loopi), x, y )

                // 对单位造成伤害，并且删除弹道
                set ecthid = GetHandleId(LoadEffectHandle(skht, tid, 20 + loopi))
                set total = LoadInteger(skht, ecthid, StringHash("穿透个数"))
                set count = LoadInteger(skht, ecthid, StringHash("当前穿透个数"))

                // TODO 数量，地形
                if count > total then
                    call DestroyEffect(LoadEffectHandle(skht, tid, 20 + loopi))
                    call RemoveSavedHandle(skht, tid, 20 + loopi)
                else
                    call hbj_boom_damage(uid, tid, 20 + loopi, ecthid, x, y, 60.0, FF_GetAttack(udg_player_select_hero[uid]) * 0.1 * (1.0 + ct_hbjBoomDmgZf[uid]), LoadUnitHandle(skht, tid, 30))
                endif
            endif

            set firstLineAngle = firstLineAngle + inAngle
            set loopi = loopi + 1
        endloop

        // 退出计时
        call SaveReal(skht, tid, 4, jl)
        if(jl >= totalJl) then

            set loopi = 0
            loop
                exitwhen loopi >= num
                set ecthid = GetHandleId(LoadEffectHandle(skht, tid, 20 + loopi))
                call DestroyEffect(LoadEffectHandle(skht, tid, 20 + loopi))
                call FlushChildHashtable(skht, ecthid)
                set loopi = loopi + 1
            endloop
            call FlushChildHashtable(skht, tid)
            call PauseTimer(t)
            call DestroyTimer(t)
        endif
    
        set t = null
    endfunction

    // 释放2 速度稍微快点，目前只有攻家BOSS在使用
    function relHanbjBoomAtk takes integer uid, real order_x, real order_y, real distance, real angle, real inAngle, integer num, real height, string mdl, unit bu returns nothing

        
        // uid - 释放玩家
        // order_x - 中心点x
        // order_y - 中心点y
        // distance - 每根线的长度距离
        // angle - 角度：箭矢射向的方向
        // inAngle - 夹角角度
        // num - 扇形数量
        // mdl - 特效模型
        // height - 特效高度
        
        // 1 根线的时候 角度是0
        // 2 根线 有 一个夹角  3 根线 有 两个夹角 也就是 num-1就是夹角数量
        // 问题在于求出第一个线的角度？
        // 1 根线的时候 角度是0                         0个夹角0
        // 2 根线的时候 角度是 angle/2                  半个夹角0.5
        // 3 根线的时候 角度是 angle                    一个夹角1
        // 4 根线的时候 角度是 angle/2 + angle          一个半夹角1.5
        // 5 根线的时候 角度是 angle*2                  两个夹角2
        // 6 根线的时候 角度是 angle/2 + angle*2        两个半夹角2.5
        // 7 根线的时候 角度是 angle + angle*2          三个夹角3

        // 第一条线的角度
        local real firstLineAngle
        local integer loopi
        local real jd
        local timer t
        local integer tid
        local effect ect
        local integer ecthid

        // 根据线的条数求出第一个线的角度
        // (num - 1) * 0.5
        set firstLineAngle = angle - I2R(num - 1) * 0.5 * inAngle

        set t = CreateTimer()
        set tid = GetHandleId(t)
        call SaveInteger(skht, tid, 1, uid)
        call SaveInteger(skht, tid, 2, num)
        call SaveReal(skht, tid, 3, firstLineAngle)
        call SaveReal(skht, tid, 5, inAngle)
        call SaveReal(skht, tid, 6, order_x)
        call SaveReal(skht, tid, 7, order_y)
        // 距离
        call SaveReal(skht, tid, 12, distance)
        call SaveUnitHandle(skht, tid, 30, bu)
        
        set loopi = 0
        loop
            exitwhen loopi >= num
            
            set ect = AddSpecialEffect(mdl, order_x, order_y)
            call EXSetEffectZ( ect, getZByXY(order_x, order_y) + height )
            call EXEffectMatRotateZ(ect, firstLineAngle)

            call SaveEffectHandle(skht, tid, 20 + loopi, ect)    

            // 弹道要穿透的单位个数，最多20个  为0表示不穿透
            // 子key 1 - 穿透数量用来保存穿透的单位handid,避免重复穿透
            // 当前穿透的个数 达到 穿透个数结束弹道
            set ecthid = GetHandleId(ect)
            call SaveInteger(skht, ecthid, StringHash("穿透个数"), ct_hbjBoomPZCount[uid])
            call SaveInteger(skht, ecthid, StringHash("当前穿透个数"), 0)


            set firstLineAngle = firstLineAngle + inAngle
            set loopi = loopi + 1
        endloop

        call TimerStart(t, 0.02, true, function timer_hbj_boom)

        set mdl = null
        set t = null
        set ect = null
    endfunction

endlibrary



